import os
import json
import socket
import psycopg2
#from events.h_create_dir import CreateShot
"""
该文件为挂载服务器上的服务脚本，功能是用来监听各客户端传来的请求信息，并返回查询结果。

GetInfo类:主要用来获取数据库连接。其中init_connect连接的是排期系统数据库，init_houdini_connect连接的是cgtw项目路径存储信息库

CreateShot类:查询项目、集数、镜头信息

CreateServer类:监听服务，用来获取各客户端传来的查询信息
"""


class GetInfo(object):
    """
    从本地数据块222中读取镜头信息
    """
    def __init__(self):
        super(GetInfo, self).__init__()


    def init_connect(self):
        """
        连接排期系统数据库
        :return:
        """
        try:
            time_connect = psycopg2.connect(database='postgres',
                                          user='timeaxis',
                                          password='timeaxis',
                                          host='192.168.1.222',
                                          port=5432)
            time_cursor = time_connect.cursor()
        except Exception as cgdb_err:
            print(str(cgdb_err))

            return None, None
        return time_connect, time_cursor

    # def init_houdini_connect(self):
    #     """
    #     连接houdini数据库
    #     :return:
    #     """
    #     try:
    #         time_connect = psycopg2.connect(database='houdini',
    #                                       user='timeaxis',
    #                                       password='timeaxis',
    #                                       host='192.168.1.222',
    #                                       port=5432)
    #         time_cursor = time_connect.cursor()
    #     except Exception as cgdb_err:
    #         print(str(cgdb_err))
    #
    #         return None, None
    #     return time_connect, time_cursor


    def get_projects(self):
        """
        获取项目列表
        :return:{'MZDYY': {'database': 'proj_mzdyy', 'entity_name': 'MZDYY', 'full_name': '蜜汁炖鱿鱼', 'eps_list': ['CSGOretake', '01', '02', '03', '04', '05', '06', '10', '11', '13', '14', '16', '17', '18', '19', '20', '21', '22', '23', '25', '26', '29', '30', '31', '32', '34', '36', '37', '38', '40', '41', 'part1', '0000'], 'fps': '25'},
         'GJWD': {'database': 'proj_gjwd', 'entity_name': 'GJWD', 'full_name': '古剑网大', 'eps_list': ['test', 'eps01', 'eps02', 'color', 'layout'], 'fps': '24'},
            ...}
        """
        project_data={}

        project_sql="select database,entity_name,full_name,eps,frame_rate,resolution,path from timeaxis.r_project where status = 'Active'"
        time_connect, time_cursor=self.init_connect()
        try:
            time_cursor.execute(project_sql)
            result=time_cursor.fetchall()
            if result:
                for i in result:
                    data={}
                    database=i[0]
                    entity_name=i[1]
                    # print(entity_name)
                    full_name=i[2]
                    eps_list=i[3]['eps_list']
                    fps=i[4]
                    resolution=i[5]
                    path=i[6]
                    data['database']=database
                    data['entity_name'] = entity_name
                    data['full_name'] = full_name
                    data['eps_list'] = '|'.join(eps_list) if eps_list else ''
                    data['fps'] = fps
                    data['resolution'] = resolution
                    data['path'] = path
                    if entity_name not in project_data.keys():
                        project_data[entity_name] = data

        except Exception as get_projects_ERR:
            print(str(get_projects_ERR))
        finally:
            time_connect.close()


        return project_data

    def get_asset(self,database):
        """
         根据给的项目与集数，获取该集数下的所有镜头
        :return:
        """
        asset_data={}
        asset_sql="select description,entity_name,frame from timeaxis.r_asset where cg_id similar to '({}%)'".format(database)
        time_connect, time_cursor=self.init_connect()
        try:
            time_cursor.execute(asset_sql)
            result=time_cursor.fetchall()
            if result:
                for i in result:
                    data={}
                    description=i[0]
                    entity_name=i[1]
                    frame=i[2]
                    data['description']=''
                    #data['description']=description#.replace('（','<').replace('）','>').replace('(','<').replace(')','>').replace('【','<').replace('】','>')
                    #print(data['description'])
                    data['entity_name'] = entity_name
                    data['img_path'] = 'path'#img_path
                    data['frame'] = frame
                    if entity_name not in asset_data.keys():
                        asset_data[entity_name]=data

        except Exception as get_asset_ERR:
            print(str(get_asset_ERR))
        finally:
            time_connect.close()
        return asset_data

    def get_shots(self,database,eps):
        """
         根据给的项目与集数，获取该集数下的所有镜头
        :return:
        """
        shot_data={}
        shot_sql="select description,entity_name,img_path,frame from timeaxis.r_shot where cg_id similar to '({}%)'" \
                 " and eps ='{}'".format(database,eps)
        time_connect, time_cursor=self.init_connect()
        try:
            time_cursor.execute(shot_sql)
            result=time_cursor.fetchall()
            if result:
                for i in result:
                    data={}
                    description=i[0]
                    entity_name=i[1]
                    img_path=i[2]
                    frame=i[3]
                    data['description']=''
                    #data['description']=description#.replace('（','<').replace('）','>').replace('(','<').replace(')','>').replace('【','<').replace('】','>')
                    #print(data['description'])
                    data['entity_name'] = entity_name
                    data['img_path'] = 'path'#img_path
                    data['frame'] = frame
                    if entity_name not in shot_data.keys():
                        shot_data[entity_name]=data

        except Exception as get_shots_ERR:
            print(str(get_shots_ERR))
        finally:
            time_connect.close()

        return shot_data

    def get_tasks(self,database,pipeline,shotname):
        """
        根据传来的镜头号来返回该镜头下的所有task任务的id以及task_name等信息
        :param database:
        :param pipeline:阶段名称，必须保证task_name必须以阶段名称为开头eg: efx_汽车
        :param shotname:
        :return: {'efx':{'cg_id':cg_id,'task_name':efx},'efx_汽车交互':{'cg_id':cg_id,'task_name':efx_汽车交互}}
        """
        task_data={}
        task_sql="select cg_id,task_name from timeaxis.r_task where database='{}' and  shot_name= '{}' and task_name similar to '({}%)' ".format(database,shotname,pipeline)
        time_connect, time_cursor=self.init_connect()
        try:
            time_cursor.execute(task_sql)
            result=time_cursor.fetchall()
            if result:
                for i in result:
                    data={}
                    cg_id=i[0]
                    task_name=i[1]
                    data['cg_id']=cg_id
                    data['task_name'] = task_name
                    if task_name not in task_data.keys():
                        task_data[task_name]=data

        except Exception as get_shots_ERR:
            print(str(get_shots_ERR))
        finally:
            time_connect.close()

        return task_data



    # def get_project_config(self,project_entity_name):
    #     """
    #     给定项目简称,查询项目所在的ip路径
    #     :param project_entity_name:
    #     :return:
    #     """
    #     data={}
    #     time_connect, time_cursor=self.init_houdini_connect()
    #     sql="select fps,color,resolution,path,fullname,entityname from projectconfig where entityname = '{}'".format(project_entity_name)
    #     try:
    #         time_cursor.execute(sql)
    #         i=time_cursor.fetchone()
    #         if i:
    #             data['fps']=i[0]
    #             data['color']=i[1]
    #             data['resolution']=i[2]
    #             data['path']=i[3]
    #             data['full_name']=i[4]
    #             data['entity_name']=i[5]
    #             # path=data['path']
    #     except Exception as get_path_ERR:
    #         print('get_path_ERR:',str(get_path_ERR))
    #     finally:
    #         time_connect.close()
    #     #print(data)
    #     return data

class CreateShot(object):
    def __init__(self):
        super(CreateShot, self).__init__()

        self.CONF_PATH=os.path.join(os.path.dirname(__file__),"config")
        self.CONF_PATH = "config"
        self.ip=self.get_ip(self.CONF_PATH)


    def get_ip(self,config_path):
        data={}
        with open(config_path,'r',encoding='utf8') as r:
            data=eval(r.read())
        ip='\\\\'+data['path']
        print('ip:',ip)
        return ip

    def create_shot(self,data):
        """
        根据传来的信号生成目录结构
        :param data: {"project":xxx,"eps":xxx,"shot":xxx,"task":xxx}
        :return:
        """
        if data:
            project=data['project']
            eps=data['eps']
            shot=data['shot']
            pipeline=data['pipeline']
            print(self.ip,project,eps,shot)
            shot_path=os.path.join(self.ip,project,eps,shot,pipeline)
            # print('create_shot:',shot_path)
            if not os.path.exists(shot_path):
                os.makedirs(shot_path)
            dir_list=['hip','geo','cam','abc','render','tex','sim']
            for i in dir_list:
                path=os.path.join(shot_path,i)
                if not os.path.exists(path):
                    os.makedirs(path)
            #最后将该镜头的信息写入
            shot_info_path=os.path.join(shot_path,'shot.info')
            with open(shot_info_path,'w',encoding='utf8') as w:
                w.write(str(data))


class CreateServer(object):
    def __init__(self):
        super(CreateServer, self).__init__()
        # self.c = CreateShot()
        self.get_info_handler=GetInfo()

    def runServer(self,host, port, buffer):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        sock.bind((host, port))
        sock.listen(150)
        # self.load_debug('启动服务')
        print('servering listening')
        while True:
            try:
                client_sock, client_addr = sock.accept()
                # all_data = b''
                # while True:
                #     recv = client_sock.recv(buffer)
                #     all_data+=recv
                #     if not recv:
                #         break
                recv = client_sock.recv(buffer)
                if recv:
                    print('接到recv')
                    #all_data = client_sock.recv(buffer)
                    #print('all_data:',all_data)
                    #data = eval(all_data.decode())
                    data=eval(recv.decode())
                    #print('data:',data)
                    if data['ask_type']=='project':
                        # print('ask_type,database')
                        print('请求了project')
                        project_data=self.get_info_handler.get_projects()
                        # print(type(project_data))
                        # print(json.dumps(project_data))
                        if project_data:
                            client_sock.send(str(project_data).encode())
                        else:
                            client_sock.send('404'.encode())
                    elif data['ask_type']=='shot':
                        # print('ask_type,shot')
                        database=data['database']
                        eps=data['eps']
                        shot_data=self.get_info_handler.get_shots(database,eps)
                        if shot_data:
                            client_sock.send(str(shot_data).encode())
                        else:
                            client_sock.send('404'.encode())
                    elif data['ask_type']=='asset':
                        # print('ask_type,asset')
                        database=data['database']
                        eps=data['eps']
                        shot_data=self.get_info_handler.get_shots(database,eps)
                        if shot_data:
                            client_sock.send(str(shot_data).encode())
                        else:
                            client_sock.send('404'.encode())

                    elif data['ask_type']=='task':  #nuke提交时需要获取具体的task的id选项
                        database=data['database']
                        # eps=data['eps']
                        shot_name=data['shot_name']
                        pipeline=data['pipeline']
                        task_data=self.get_info_handler.get_tasks(database,pipeline,shot_name)
                        if task_data:
                            client_sock.send(str(task_data).encode())
                        else:
                            client_sock.send('404'.encode())
                    # elif data['ask_type']=='config':
                    #     entity_name=data['entity_name']
                    #     path=self.get_info_handler.get_project_config(entity_name)
                    #     if path:
                    #         client_sock.send(str(path).encode())
                    #     else:
                    #         client_sock.send('404'.encode())
                    # else:
                    #     print('Wrong ask_type')


            except Exception as runServer_ERR:
                print('runServer_ERR:',str(runServer_ERR))


if __name__ == '__main__':
    HOST='192.168.1.178' #连到mac上先
    # HOST='192.168.1.222'
    PORT =5566
    BUFFER = 1024
    mys = CreateServer()
    mys.runServer(HOST, PORT, BUFFER)

    # g=GetInfo()
    # project_data=g.get_projects()
    # print(project_data)
    # shot_data=g.get_shots('proj_my','01')
    # print(shot_data)
    # print(len(shot_data.keys()))